// ==============================================================================
// MessageReceiverGateway provides functionality for receiving messages 
// synchronously from MSMQ.
// 
// MessageReceiverGateway.cs
// @author Abel Perez <java.aperez@gmail.com>
// ==============================================================================

#region Imports

using System;
using System.IO;
using System.Messaging;
using System.Xml;

#endregion

namespace Justa.Messaging
{
    /// <summary>
    /// MessageReceiverGateway provides functionality for receiving messages 
    /// synchronously from MSMQ.
    /// 
    /// <list type="bullet">
    /// <item>
    /// <term>Author</term>
    /// <description>Abel Perez (java.aperez@gmail.com)</description>
    /// </item>
    /// </list>
    /// </summary>
    /// <remarks>
    /// The core of the operations provides by this gateway are all related to 
    /// receving messages from MSMQ synchronously.  This gateway can either 
    /// block indefinatly, block until a specified timeout is reached, or 
    /// return imediately if no messages are available in the target destination.  
    /// The default message formatter used by this gateway is an XML message 
    /// formatter, the most common use for this gateway is to recieve xml based 
    /// messages.
    /// </remarks>
    /// 
    /// <example>
    /// The following code example demonstrates receiving an message from the 
    /// specified destination and synchronously blocking until a response 
    /// message is received or the specified timeout is exceeded.
    /// 
    /// <code>
    ///     string destination = "Unified.AutoLoan.CarsDirect.Ping";
    ///     string name = "CarsDirectGateway";
    ///     string requestMessage = "<ping>Hello World</ping>";
    ///     
    ///     MessageReceiverGateway gateway = new MessageReceiverGateway(destination, name);
    ///     string responseMessage = gateway.Receive(requestMessage, 15);
    /// </code>
    /// </example>
    /// 
    public class MessageReceiverGateway : GenericMessageGateway
    {
        /// <summary>
        /// The default message queue this gateway will receive messages from.
        /// </summary>
        private MessageQueue messageQueue;


        /// <summary>
        /// Constructs this gateway with the given destination as the default message
        /// queue this gateway will receive messages from.  
        /// </summary>
        /// 
        /// <param name="destination">The default destinationthis gateway will send messages too.</param>
        public MessageReceiverGateway(string destination)
            : this(destination, null)
        {
        }

        /// <summary>
        /// Constructs this gateway with the specified destination and name.
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="name"></param>
        public MessageReceiverGateway(string destination, string name)
        {
            if (name == null)
            {
                this.Name = DEFAULT_NAME;
            }
            else
            {
                this.Name = name;
            }

            this.messageQueue = GetMessageQueue(destination);
            if (messageQueue == null)
            {
                throw new ApplicationException("Failed to initialize MessageReceiverGateway.");
            }

            this.messageQueue.Formatter = new System.Messaging.XmlMessageFormatter(new String[] { "System.String" });
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <returns></returns>
        /// 
        public string Receive()
        {
            Message response = this.messageQueue.Receive();
            return MessageRecieved(response);
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="timeout"></param>
        /// <returns></returns>
        /// 
        public string Receive(int timeout)
        {
            Message response = this.messageQueue.Receive(new System.TimeSpan(0, 0, timeout));
            return MessageRecieved(response);
        }

        /// <summary>
        /// 
        /// </summary>
        protected MessageQueue InternalMessageQueue
        {
            get { return this.messageQueue; }
            set { this.messageQueue = value; }
        }
    }
}